home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HyperLib 1997 Winter - Disc 1
/
HYPERLIB-1997-Winter-CD1.ISO.7z
/
HYPERLIB-1997-Winter-CD1.ISO
/
オンラインウェア
/
UTIL
/
Folder・Icon・Opener 1.0.1.sit
/
Folder•Icon•Opener 1.0.1
/
source code
/
sources
/
FIOpen.send.c
< prev
Wrap
Text File
|
1996-05-05
|
9KB
|
283 lines
/*
*--------------------------------------------------------------
* FIOpen.send.c
*--------------------------------------------------------------
*/
#include <Files.h>
#include <Processes.h>
#include <AppleEvents.h>
#include <AERegistry.h>
#include "FIOpen.h"
/* static functions */
static OSErr SendOpenDocToApp(ProcessSerialNumberPtr, const FSSpecPtr);
static OSErr SendMyAppleEvent(AEAddressDesc *, AEDescList *, const AEEventID);
static OSErr LaunchAppWithDoc(const FSSpecPtr app, const FSSpecPtr doc);
static OSErr LaunchAppWithAEDesc(const FSSpecPtr, AEDescList *);
static OSErr MakeMyDocDescList(const FSSpecPtr, AEDescList *);
static OSErr FindAProcessByFSS(const FSSpecPtr, ProcessSerialNumberPtr);
/*
*--------------------------------------------------------------
* PassFileToApp
*--------------------------------------------------------------
* send the file spec to the application
*--------------------------------------------------------------
*/
OSErr PassFileToApp(const FSSpecPtr theApp, const FSSpecPtr theDoc)
{
ProcessSerialNumber appPSN;
OSErr result;
result = FindAProcessByFSS(theApp, &appPSN);
if (result == noErr) {
/* the process is already running */
result = SendOpenDocToApp(&appPSN, theDoc);
if (result == noErr) {
/* let the application be in front */
result = SetFrontProcess(&appPSN);
}
} else {
/* let the icon file to be opened */
result = LaunchAppWithDoc(theApp, theDoc);
}
if (result != noErr) {
AEErrorAlert(theDoc->name);
}
return (result);
}
/*
*--------------------------------------------------------------
* SendOpenDocToApp
*--------------------------------------------------------------
* send Open Document AppleEvent to the designated application
*--------------------------------------------------------------
*/
static OSErr SendOpenDocToApp(
ProcessSerialNumberPtr thePSN,
const FSSpecPtr theDocSpec)
{
AEAddressDesc targetAddress = {typeNull, nil};
AEDescList myDocList = {typeNull, nil};
OSErr result;
/* create a descriptor of the application with its ProcessSerialNumber */
result = AECreateDesc(typeProcessSerialNumber, thePSN,
sizeof(ProcessSerialNumber), &targetAddress);
/* create a descriptor list of the document */
if (result == noErr) {
result = MakeMyDocDescList(theDocSpec, &myDocList);
}
/* send an AppleEvent to the application along with the documet list */
if (result == noErr) {
result = SendMyAppleEvent(&targetAddress, &myDocList, kAEOpenDocuments);
}
/* cleanup */
AEDisposeDesc(&targetAddress);
AEDisposeDesc(&myDocList);
return (result);
}
/*
*--------------------------------------------------------------
* SendMyAppleEvent
*--------------------------------------------------------------
* send AppleEvent with the target application's address and
* the descriptor of the file
*--------------------------------------------------------------
*/
static OSErr SendMyAppleEvent(
AEAddressDesc *theTargetAddress,
AEDescList *theDocDesc,
const AEEventID theAEKind)
{
AppleEvent myAppleEvent = {typeNull, nil};
OSErr result;
/* create an AppleEvent record to be sent */
result = AECreateAppleEvent(kCoreEventClass, theAEKind, theTargetAddress,
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
/* put the document list into the AppleEvent */
if (result == noErr) {
result = AEPutParamDesc(&myAppleEvent, keyDirectObject, theDocDesc);
}
/* now send the AppleEvent */
if (result == noErr) {
AppleEvent nullRepy = {typeNull, nil};
result = AESend(&myAppleEvent, &nullRepy,
kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer,
kAENormalPriority, kAEDefaultTimeout, nil, nil);
}
/* cleanup */
AEDisposeDesc(theTargetAddress);
AEDisposeDesc(theDocDesc);
AEDisposeDesc(&myAppleEvent);
return (result);
}
/*
*--------------------------------------------------------------
* LaunchAppWithDoc
*--------------------------------------------------------------
* launch application with 'odoc' AppleEvent
*--------------------------------------------------------------
*/
static OSErr LaunchAppWithDoc(const FSSpecPtr theAppSpec, const FSSpecPtr theDocSpec)
{
AEDescList itsDocList = {typeNull, nil};
OSErr result;
result = MakeMyDocDescList(theDocSpec, &itsDocList);
if (result == noErr) {
result = LaunchAppWithAEDesc(theAppSpec, &itsDocList);
}
return (result);
}
/*
*--------------------------------------------------------------
* LaunchAppWithAEDesc
*--------------------------------------------------------------
* Launch specified application with doc list
* FSSpec should be the application spec and
* AEDescList should be the document descriptor
*--------------------------------------------------------------
*/
static OSErr LaunchAppWithAEDesc(const FSSpecPtr theAppSpec, AEDescList *theDocDesc)
{
LaunchParamBlockRec launchPrm;
ProcessSerialNumber myPSN;
AppleEvent myAppleEvent = {typeNull, nil};
AEDesc targetDesc = {typeNull, nil};
AEDesc launchDesc = {typeNull, nil};
OSErr result;
/* get the ProcessSerialNumber of myself */
result = GetCurrentProcess(&myPSN);
/* create an address descriptor of myself */
if (result == noErr) {
result = AECreateDesc(typeProcessSerialNumber, (Ptr)&myPSN,
sizeof(ProcessSerialNumber), &targetDesc);
}
/* create an AppleEvent record to be sent */
if (result == noErr) {
result = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &targetDesc,
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
}
/* put the document list into the AppleEvent */
if (result == noErr) {
result = AEPutParamDesc(&myAppleEvent, keyDirectObject, theDocDesc);
}
/* coerce (convert) the AppleEvent into launching descriptor */
if (result == noErr) {
result = AECoerceDesc(&myAppleEvent, typeAppParameters, &launchDesc);
}
/* set the launch parameters */
if (result == noErr) {
HLock(launchDesc.dataHandle);
launchPrm.launchBlockID = extendedBlock;
launchPrm.launchEPBLength = extendedBlockLen;
launchPrm.launchFileFlags = launchNoFileFlags;
launchPrm.launchAppSpec = theAppSpec;
launchPrm.launchControlFlags = launchContinue;
launchPrm.launchAppParameters = (AppParametersPtr)(*launchDesc.dataHandle);
/* now launch it! */
result = LaunchApplication(&launchPrm);
HUnlock(launchDesc.dataHandle);
}
/* settlements */
AEDisposeDesc(theDocDesc);
AEDisposeDesc(&targetDesc);
AEDisposeDesc(&myAppleEvent);
AEDisposeDesc(&launchDesc);
return (result);
}
/*
*--------------------------------------------------------------
* MakeMyDocDescList
*--------------------------------------------------------------
* make AEDescList from FSSpec; its content is just one FSSpec
*--------------------------------------------------------------
*/
static OSErr MakeMyDocDescList(const FSSpecPtr theSpec, AEDescList *theList)
{
AEDesc itsDocDesc = {typeNull, nil};
AliasHandle itsAlias;
Size itsSize;
OSErr result = noErr;
/* create a new document list */
result = AECreateList(nil, 0, false, theList); /* new description */
/* create an alias record of the document */
if (result == noErr) {
result = NewAlias(nil, theSpec, &itsAlias);
}
if (result == noErr) {
HLock((Handle)itsAlias);
itsSize = GetHandleSize((Handle)itsAlias);
/* create a descriptor of the document alias */
result = AECreateDesc(typeAlias, (Ptr)*itsAlias, itsSize, &itsDocDesc);
/* put the alias descriptor into the document list */
if (result == noErr) {
result = AEPutDesc(theList, 0, &itsDocDesc);
}
/* dispose the alias descriptor and the alias record */
AEDisposeDesc(&itsDocDesc);
DisposeHandle((Handle)itsAlias);
}
return (result);
}
/*
*--------------------------------------------------------------
* FindAProcessByFSS
*--------------------------------------------------------------
* find the ProcessSerialNumber of the given FSSpec
*--------------------------------------------------------------
*/
static OSErr FindAProcessByFSS(
const FSSpecPtr theSpec,
ProcessSerialNumberPtr thePSN)
{
ProcessInfoRec thisInfo;
FSSpec specRec;
FSSpecPtr thisSpec = &specRec;
Str31 itsName;
/* initialize the ProcessSerialNumber */
thePSN->lowLongOfPSN = thePSN->highLongOfPSN = kNoProcess;
/* search the processes */
while (GetNextProcess(thePSN) != procNotFound) {
thisInfo.processInfoLength = sizeof(ProcessInfoRec);
thisInfo.processName = itsName;
thisInfo.processAppSpec = thisSpec;
GetProcessInformation(thePSN, &thisInfo);
/* compare the FSSpecs */
if (thisSpec->vRefNum == theSpec->vRefNum
&& thisSpec->parID == theSpec->parID
&& EqualString(thisSpec->name, theSpec->name, false, true)) {
return (noErr);
}
}
return (procNotFound);
}